package com.efast.cafe.portal.service.common.impl;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.UUID;
import java.util.stream.Collectors;

import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.ValueOperations;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.efast.cafe.framework.constant.CommonConstant;
import com.efast.cafe.framework.redis.ObjectRedisTemplate;
import com.efast.cafe.framework.util.SpringWebUtils;
import com.efast.cafe.framework.vo.TreeVo;
import com.efast.cafe.portal.dao.common.PortalResourceDao;
import com.efast.cafe.portal.entity.common.ModuleInfo;
import com.efast.cafe.portal.entity.common.ModuleMenu;
import com.efast.cafe.portal.entity.common.ModulePurview;
import com.efast.cafe.portal.entity.company.PortalCompanyRolePurview;
import com.efast.cafe.portal.service.common.IResourceService;
import com.efast.cafe.util.StringUtil;
import com.google.common.collect.Sets;

@Service
@Transactional
public class ResourceServiceImpl implements IResourceService{


	private ObjectRedisTemplate objectRedisTemplate;
	
	@Autowired
	public void setObjectRedisTemplate(ObjectRedisTemplate objectRedisTemplate) {
		this.objectRedisTemplate = objectRedisTemplate;
	}

	private PortalResourceDao portalResourceDao;
	
	@Autowired
	public void setPortalResourceDao(PortalResourceDao portalResourceDao) {
		this.portalResourceDao = portalResourceDao;
	}
	

	@Override
	public List<ModuleInfo> queryModulesByCompanyCode() {
		String companyCode = SpringWebUtils.getRequestCompany();
		ValueOperations<String,Object> redislistObj = objectRedisTemplate.opsForValue();
		//先从redis缓存服务器读取企业拥有的模块
		Object object = redislistObj.get(CommonConstant.REDIS_COMPANY_MODULE_LIST_KEY+companyCode);
		if(null==object){
			List<ModuleInfo> list = portalResourceDao.queryModulesByCompanyCode(companyCode);
			redislistObj.set(CommonConstant.REDIS_COMPANY_MODULE_LIST_KEY+companyCode, list);
			return list;
		}else{
			return (List<ModuleInfo>)object;
		}
	}

	@Override
	public List<ModuleMenu> queryMenus(Long moduleInfoId) {
		
		List<ModuleMenu> list = null;
		ValueOperations<String,Object> redislistObj = objectRedisTemplate.opsForValue();
		if(null!=moduleInfoId){
			Object obj = redislistObj.get(CommonConstant.REDIS_MODULE_MENU_LIST_KEY+"_"+moduleInfoId);
			if(null==obj){
				list = portalResourceDao.queryMenus(moduleInfoId);
				redislistObj.set(CommonConstant.REDIS_MODULE_MENU_LIST_KEY+"_"+moduleInfoId, list);
			}else{
				list = (List<ModuleMenu>)obj;
			}
		}else{
			//先从redis缓存服务器获取全部菜单
			Object obj = redislistObj.get(CommonConstant.REDIS_MODULE_MENU_LIST_KEY+"ALL");
			if(null==obj){
				list = portalResourceDao.queryMenus(null);
				redislistObj.set(CommonConstant.REDIS_MODULE_MENU_LIST_KEY+"ALL", list);
			}else{
				list = (List<ModuleMenu>)obj;
			}
		}
		return list;
	}
	

	

	@Override
	public HashSet<Long> queryPurviewByCompanyUserAndRole() {
		HashSet<Long> checkauthSet = Sets.newHashSet();
		HashSet<Long> authSet = Sets.newHashSet();
		String companyCode = SpringWebUtils.getRequestCompany();
		String username = SpringWebUtils.getRequestUser();
		ValueOperations<String,Object> redislistObj = objectRedisTemplate.opsForValue();
		//从redis缓存服务器读取用户所拥有的权限ID
		Object redisRes = redislistObj.get(CommonConstant.REDIS_COMPANYUSER_PURVIEW_IDS_KEY+companyCode+username);
		if(null==redisRes){//不存在则查询数据库 同时放入redis缓存服务器
			List<PortalCompanyRolePurview> purviewIds = portalResourceDao.queryPurviewByCompanyUserAndRole(username,companyCode);
			List<ModulePurview> mopurviewList = portalResourceDao.queryModulePurviewByCompanyCode(companyCode);
			//当前企业用户的权限ID集合
			purviewIds.forEach(mp->{checkauthSet.add(mp.getModulePurviewId());});
			//过滤企业所拥有的所有权限
			mopurviewList.stream()
			.filter(p-> checkauthSet.contains(p.getModulePurviewId()))
			.forEach(cp->{authSet.add(cp.getModuleMenuId());});
			redislistObj.set(CommonConstant.REDIS_COMPANYUSER_PURVIEW_IDS_KEY+companyCode+username, authSet);
		}else{
			HashSet<Long> authSet1 = (HashSet<Long>)redisRes;
			authSet1.forEach(na->{authSet.add(na.longValue());});
		}
		return authSet;
	}
	
	public HashSet<String> queryPurviewPathByCompanyUserAndRole(){
 		HashSet<Long> checkauthSet = Sets.newHashSet();
		HashSet<String> authSet = Sets.newHashSet();
		String companyCode = SpringWebUtils.getRequestCompany();
		String username = SpringWebUtils.getRequestUser();
		ValueOperations<String,Object> redisValueObj = objectRedisTemplate.opsForValue();
		Object object = redisValueObj.get(CommonConstant.REDIS_COMPANYUSER_PURVIEWSET_KEY+companyCode+username);
		if(null==object){
			//查询portal下企业用户所拥有的权限ID
			List<PortalCompanyRolePurview> purviewIds = portalResourceDao.queryPurviewByCompanyUserAndRole(username,companyCode);
			//查询当前企业所拥有的权限资源id
			List<ModulePurview> mopurviewList = portalResourceDao.queryModulePurviewByCompanyCode(companyCode);
			//当前企业用户的权限ID集合
			purviewIds.forEach(mp->{checkauthSet.add(mp.getModulePurviewId());});
			mopurviewList.stream().filter(
						p->checkauthSet.contains(p.getModulePurviewId())
					).forEach(mp->{
						String path = mp.getUrlPath();
						String[] pathArray = path.split("\\;");
						for(String ph : pathArray){
							if(!authSet.contains(ph)){
								authSet.add(ph);
							}
						}
					});
			redisValueObj.set(CommonConstant.REDIS_COMPANYUSER_PURVIEWSET_KEY+companyCode+username, authSet);
		}else{
			//authSet = (HashSet<String>)object;
			HashSet<String> authSet1 = (HashSet<String>)object;
			authSet1.forEach(na->{authSet.add(na);});
		}
		return authSet;
	}
	
	public HashSet<String> queryPurviewPathByCompanyUserAndRoleDB(String companyCode,String username){
 		HashSet<Long> checkauthSet = Sets.newHashSet();
		HashSet<String> authSet = Sets.newHashSet();
			//查询portal下企业用户所拥有的权限ID
			List<PortalCompanyRolePurview> purviewIds = portalResourceDao.queryPurviewByCompanyUserAndRole(username,companyCode);
			
			//查询当前企业所拥有的权限资源id
			List<ModulePurview> mopurviewList = portalResourceDao.queryModulePurviewByCompanyCode(companyCode);
			//当前企业用户的权限ID集合
			purviewIds.forEach(mp->{checkauthSet.add(mp.getModulePurviewId());});
			Map<String, List<String>> menuPurviews = new HashMap<>();//当前登录用户在某个菜单下的拥有的权限
			mopurviewList.stream().filter(p->checkauthSet.contains(p.getModulePurviewId())).forEach(np->{
				String path = np.getUrlPath();
				String[] pathArray = path.split("\\;");
				for(String ph : pathArray){
					//if(!authSet.contains(ph)){
						authSet.add(ph);
						List<String> plist= menuPurviews.get(np.getMenuPath());
						if(plist==null){
							plist = new ArrayList<>();
						}
						plist.add(ph);
						menuPurviews.put(np.getMenuPath(), plist);
					//}
				}
			});
			ValueOperations<String,Object> redisValueObj = objectRedisTemplate.opsForValue();
			redisValueObj.set(CommonConstant.REDIS_COMPANYUSER_PURVIEWSET_KEY_BY_MENU+companyCode+username, menuPurviews);
		return authSet;
	}
	
	public HashSet<String> queryAllPurviewPath(){
		HashSet<String> authSet = Sets.newHashSet();
		ValueOperations<String,Object> redisValueObj = objectRedisTemplate.opsForValue();
		Object object = redisValueObj.get(CommonConstant.REDIS_ALL_PURVIEW_PATHSET_KEY);
		if(null==object){
			List<ModulePurview> mopurviewList = portalResourceDao.queryAllModulePurview();
			for(ModulePurview p : mopurviewList){
				String path = p.getUrlPath();
				String[] pathArray = path.split("\\;");
				for(String ph : pathArray){
					if(!authSet.contains(ph)){
						authSet.add(ph);
					}
				}
			}
			if(!authSet.isEmpty()){
				redisValueObj.set(CommonConstant.REDIS_ALL_PURVIEW_PATHSET_KEY, authSet);
			}
		}else{
			authSet = (HashSet<String>)object;
		}
		return authSet;
	}
	
	public HashSet<String> queryAllPurviewPathDB(){
		HashSet<String> authSet = Sets.newHashSet();
		
			List<ModulePurview> mopurviewList = portalResourceDao.queryAllModulePurview();
			for(ModulePurview p : mopurviewList){
				String path = p.getUrlPath();
				String[] pathArray = path.split("\\;");
				for(String ph : pathArray){
					if(!authSet.contains(ph)){
						authSet.add(ph);
					}
				}
			}
			
		return authSet;
	}

	@Override
	public List<ModulePurview> queryPurviewByCompanyCode(Long moduleInfoId) {
		String companyCode = SpringWebUtils.getRequestCompany();
		//查询当前企业所拥有的权限资源id 
		List<ModulePurview> mopurviewList = portalResourceDao.queryModulePurviewByCompany(companyCode, moduleInfoId);
		return mopurviewList;
	}


	/**
	 * {@inheritDoc} 
	 * overridden:
	 * @Date        :      2016-8-18
	 * @see org.eae.eldf.portal.remote.common.ResourceService#queryCurrentUserMenusTree()
	**/
	@Override
	public List<TreeVo> queryCurrentUserMenusTree(String i18n) {
		List<ModuleInfo> moduleList = this.queryModulesByCompanyCode();
		Map<String, String> moduleMap = new HashMap<String, String>();
		for(ModuleInfo m : moduleList){
			moduleMap.put("menu_"+m.getModuleInfoId(), m.getModuleUrl());
		}
		//获取模块下的菜单
		List<ModuleMenu> menus = this.queryMenus(null);
	
		//当前企业用户所拥有的资源 
		HashSet<Long> perSet = this.queryPurviewByCompanyUserAndRole();

		Map<String, TreeVo> treeMap = new LinkedHashMap<String, TreeVo>();
		TreeVo root = new TreeVo();
		for (ModuleMenu menu : menus) {
			if((menu.getIsLeaf()!=null && menu.getIsLeaf()==0) || perSet.contains(menu.getModuleMenuId())){
				if(menu.getDisplayd()!=null && menu.getDisplayd().intValue()==0){
					continue;
				}
				TreeVo tree = new TreeVo();
				tree.setId("menu_"+menu.getModuleMenuId());
				if(StringUtils.isBlank(i18n)){
					tree.setText(menu.getMenuName());
				}else{
					if(i18n.equalsIgnoreCase(CommonConstant.I18NKeys.EN_US)){
						tree.setText(menu.getMenuNameENUS());
					}
					if(i18n.equalsIgnoreCase(CommonConstant.I18NKeys.ZH_CN)){
						tree.setText(menu.getMenuNameZHCN());
					}
					if(StringUtils.isBlank(tree.getText())){
						tree.setText(menu.getMenuName());
					}
				}
				
				
				tree.setLeaf(menu.getIsLeaf()==0?false:true);
				tree.setIcon(StringUtils.isBlank(menu.getIconCls())?"":menu.getIconCls());
				tree.setParentId(menu.getParentId()!=0?"menu_"+menu.getParentId():null);
				//if(menu.getIsLeaf()==1){
					if(StringUtil.isNotBlank(menu.getMenuPath()))
						tree.setUrl(moduleMap.get("menu_"+menu.getModuleInfoId())+menu.getMenuPath());
				//}
				treeMap.put("menu_"+menu.getModuleMenuId(), tree);
			}
		}
		Iterator<Map.Entry<String, TreeVo>> it = treeMap.entrySet().iterator();
		while (it.hasNext()) {
			Map.Entry<String, TreeVo> entry = it.next();
			TreeVo tree = entry.getValue();
			if (StringUtils.isBlank(tree.getParentId())) {
				root.getMenus().add(tree);
			}else{
				TreeVo parent = treeMap.get(tree.getParentId());// 根据父Id查询
				if (parent != null) {
					parent.getMenus().add(tree);
				}
			}
		}
		root.removeNoRight();
		return root.getMenus();
	}

	

	
	
	

}
